home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / Mail / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-08  |  6.1 KB  |  276 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. char copyright[] =
  20. "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  21.  All rights reserved.\n";
  22. #endif /* not lint */
  23.  
  24. #ifndef lint
  25. static char sccsid[] = "@(#)main.c    5.22 (Berkeley) 2/13/89";
  26. #endif /* not lint */
  27.  
  28. #include "rcv.h"
  29. #include <sys/stat.h>
  30.  
  31. /*
  32.  * Mail -- a mail program
  33.  *
  34.  * Startup -- interface with user.
  35.  */
  36.  
  37. jmp_buf    hdrjmp;
  38.  
  39. main(argc, argv)
  40.     char **argv;
  41. {
  42.     register int i;
  43.     struct name *to, *cc, *bcc, *smopts;
  44.     char *subject;
  45.     char *ef;
  46.     char nosrc = 0;
  47.     int hdrstop(), (*prevint)();
  48.     int sigchild();
  49.     extern int getopt(), optind, opterr;
  50.     extern char *optarg;
  51.  
  52.     /*
  53.      * Set up a reasonable environment.
  54.      * Figure out whether we are being run interactively,
  55.      * start the SIGCHLD catcher, and so forth.
  56.      */
  57.     (void) signal(SIGCHLD, sigchild);
  58.     if (isatty(0))
  59.         assign("interactive", "");
  60.     image = -1;
  61.     /*
  62.      * Now, determine how we are being used.
  63.      * We successively pick off - flags.
  64.      * If there is anything left, it is the base of the list
  65.      * of users to mail to.  Argp will be set to point to the
  66.      * first of these users.
  67.      */
  68.     ef = NOSTR;
  69.     to = NIL;
  70.     cc = NIL;
  71.     bcc = NIL;
  72.     smopts = NIL;
  73.     subject = NOSTR;
  74.     while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != EOF) {
  75.         switch (i) {
  76.         case 'T':
  77.             /*
  78.              * Next argument is temp file to write which
  79.              * articles have been read/deleted for netnews.
  80.              */
  81.             Tflag = optarg;
  82.             if ((i = creat(Tflag, 0600)) < 0) {
  83.                 perror(Tflag);
  84.                 exit(1);
  85.             }
  86.             close(i);
  87.             break;
  88.         case 'u':
  89.             /*
  90.              * Next argument is person to pretend to be.
  91.              */
  92.             myname = optarg;
  93.             break;
  94.         case 'i':
  95.             /*
  96.              * User wants to ignore interrupts.
  97.              * Set the variable "ignore"
  98.              */
  99.             assign("ignore", "");
  100.             break;
  101.         case 'd':
  102.             debug++;
  103.             break;
  104.         case 's':
  105.             /*
  106.              * Give a subject field for sending from
  107.              * non terminal
  108.              */
  109.             subject = optarg;
  110.             break;
  111.         case 'f':
  112.             /*
  113.              * User is specifying file to "edit" with Mail,
  114.              * as opposed to reading system mailbox.
  115.              * If no argument is given after -f, we read his
  116.              * mbox file.
  117.              *
  118.              * getopt() can't handle optional arguments, so here
  119.              * is an ugly hack to get around it.
  120.              */
  121.             if ((argv[optind]) && (argv[optind][0] != '-'))
  122.                 ef = argv[optind++];
  123.             else
  124.                 ef = "&";
  125.             break;
  126.         case 'n':
  127.             /*
  128.              * User doesn't want to source /usr/lib/Mail.rc
  129.              */
  130.             nosrc++;
  131.             break;
  132.         case 'N':
  133.             /*
  134.              * Avoid initial header printing.
  135.              */
  136.             assign("noheader", "");
  137.             break;
  138.         case 'v':
  139.             /*
  140.              * Send mailer verbose flag
  141.              */
  142.             assign("verbose", "");
  143.             break;
  144.         case 'I':
  145.             /*
  146.              * We're interactive
  147.              */
  148.             assign("interactive", "");
  149.             break;
  150.         case 'c':
  151.             /*
  152.              * Get Carbon Copy Recipient list
  153.              */
  154.             cc = cat(cc, nalloc(optarg, GCC));
  155.             break;
  156.         case 'b':
  157.             /*
  158.              * Get Blind Carbon Copy Recipient list
  159.              */
  160.             bcc = cat(bcc, nalloc(optarg, GBCC));
  161.             break;
  162.         case '?':
  163.             fputs("\
  164. Usage: mail [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
  165.             [- sendmail-options ...]\n\
  166.        mail [-iInNv] -f [name]\n\
  167.        mail [-iInNv] [-u user]\n",
  168.                 stderr);
  169.             exit(1);
  170.         }
  171.     }
  172.     for (i = optind; (argv[i]) && (*argv[i] != '-'); i++)
  173.         to = cat(to, nalloc(argv[i], GTO));
  174.     for (; argv[i]; i++)
  175.         smopts = cat(smopts, nalloc(argv[i], 0));
  176.     /*
  177.      * Check for inconsistent arguments.
  178.      */
  179.     if (to == NIL && (subject != NOSTR || cc != NIL || bcc != NIL)) {
  180.         fputs("You must specify direct recipients with -s, -c, or -b.\n", stderr);
  181.         exit(1);
  182.     }
  183.     if (ef != NOSTR && to != NIL) {
  184.         fprintf(stderr, "Cannot give -f and people to send to.\n");
  185.         exit(1);
  186.     }
  187.     tinit();
  188.     setscreensize();
  189.     input = stdin;
  190.     rcvmode = !to;
  191.     spreserve();
  192.     if (!nosrc)
  193.         load(MASTER);
  194.     /*
  195.      * Expand returns a savestr, but load only uses the file name
  196.      * for fopen, so it's save to do this.
  197.      */
  198.     load(expand("~/.mailrc"));
  199.     if (!rcvmode) {
  200.         mail(to, cc, bcc, smopts, subject);
  201.         /*
  202.          * why wait?
  203.          */
  204.         exit(senderr);
  205.     }
  206.     /*
  207.      * Ok, we are reading mail.
  208.      * Decide whether we are editing a mailbox or reading
  209.      * the system mailbox, and open up the right stuff.
  210.      */
  211.     if (ef == NOSTR)
  212.         ef = "%";
  213.     if (setfile(ef) < 0)
  214.         exit(1);        /* error already reported */
  215.     if (setjmp(hdrjmp) == 0) {
  216.         extern char *version;
  217.  
  218.         if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
  219.             signal(SIGINT, hdrstop);
  220.         if (value("quiet") == NOSTR)
  221.             printf("Mail version %s.  Type ? for help.\n",
  222.                 version);
  223.         announce();
  224.         fflush(stdout);
  225.         signal(SIGINT, prevint);
  226.     }
  227.     commands();
  228.     signal(SIGHUP, SIG_IGN);
  229.     signal(SIGINT, SIG_IGN);
  230.     signal(SIGQUIT, SIG_IGN);
  231.     quit();
  232.     exit(0);
  233. }
  234.  
  235. /*
  236.  * Interrupt printing of the headers.
  237.  */
  238. hdrstop()
  239. {
  240.  
  241.     fflush(stdout);
  242.     fprintf(stderr, "\nInterrupt\n");
  243.     longjmp(hdrjmp, 1);
  244. }
  245.  
  246. /*
  247.  * Compute what the screen size for printing headers should be.
  248.  * We use the following algorithm for the height:
  249.  *    If baud rate < 1200, use  9
  250.  *    If baud rate = 1200, use 14
  251.  *    If baud rate > 1200, use 24 or ws_row
  252.  * Width is either 80 or ws_col;
  253.  */
  254. setscreensize()
  255. {
  256.     struct sgttyb tbuf;
  257.     struct winsize ws;
  258.  
  259.     if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0)
  260.         ws.ws_col = ws.ws_row = 0;
  261.     if (gtty(1, &tbuf) < 0)
  262.         tbuf.sg_ospeed = B9600;
  263.     if (tbuf.sg_ospeed < B1200)
  264.         screenheight = 9;
  265.     else if (tbuf.sg_ospeed == B1200)
  266.         screenheight = 14;
  267.     else if (ws.ws_row != 0)
  268.         screenheight = ws.ws_row;
  269.     else
  270.         screenheight = 24;
  271.     if ((realscreenheight = ws.ws_row) == 0)
  272.         realscreenheight = 24;
  273.     if ((screenwidth = ws.ws_col) == 0)
  274.         screenwidth = 80;
  275. }
  276.